package com.ingenio.dao;


import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.ingenio.Adapter;
import com.ingenio.business.EstadoProducto;
import com.ingenio.business.Marca;
import com.ingenio.business.Producto;
import com.ingenio.business.Proveedor;
import com.ingenio.business.SubRubro;
import com.ingenio.business.UMProducto;
import com.ingenio.business.UnidadMedida;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

public class ProductoAdapter extends Adapter{
	
	public Producto devolverProducto(String id) throws Exception{
    	Connection conn = null;
    	Producto p = null;
    	PreparedStatement stmt = null;
    	try {
    		conn = (Connection) abrirConexion();
    		String sel ="SELECT * FROM producto WHERE IdProducto = ? and prodHabilitado=1";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setString(1, id);
    		ResultSet result = stmt.executeQuery();
    		
    		EstadoProducto ep = null;
    		EstadoProductoAdapter epa = new EstadoProductoAdapter();
    		
    		UnidadMedida um = null;
    		UnidadMedidaAdapter uma = new UnidadMedidaAdapter();
    		
    		Marca m = null;
    		MarcaAdapter ma = new MarcaAdapter();
    		
    		SubRubro sr = null;
    		SubRubroAdapter sra = new SubRubroAdapter();
    		
    		List<UMProducto> umsp = null;
    		UMProductoAdapter umpa = new UMProductoAdapter();
    		
    		if(result.next()){
    			String descripcion = result.getString("descProducto");
    			String caracteristicas = result.getString("caracteristicasProd");
    			Integer IdEstadoProducto = result.getInt("IdEstadoProducto");
    			Integer IdUmStock = result.getInt("IdUmStock");
    			Integer IdMarca = result.getInt("IdMarca");
    			Integer IdSubRubro = result.getInt("IdSubRubro");
    			ep = epa.devolverEstadoProducto(IdEstadoProducto);
    			um = uma.devolverUnidadMedida(IdUmStock);
    			m = ma.devolverMarca(IdMarca);
    			sr = sra.devolverSubRubro(IdSubRubro);
    			p = new Producto(id, descripcion, ep, um, m, sr, caracteristicas, true);
    			umsp = umpa.devolverUMProducto(p);
    			p.setUmsProducto(umsp);
    		}
    	}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		//conn.close();
    		cerrarConexion(conn);
    	}
		return p;
    }
	
	
	public Producto devolverProductoProveedor(String id, Proveedor proveedor) throws Exception{
    	Connection conn = null;
    	Producto p = null;
    	PreparedStatement stmt = null;
    	try {
    		conn = (Connection) abrirConexion();
    		String sel ="SELECT * FROM producto p " +
    				"INNER JOIN proveedor_producto pp on pp.IdProducto = p.IdProducto " +
    				"WHERE p.IdProducto = ? and prodHabilitado=1 and pp.IdProveedor = ?";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setString(1, id);
    		stmt.setInt(2, proveedor.getIdProvedoor());
    		ResultSet result = stmt.executeQuery();
    		
    		EstadoProducto ep = null;
    		EstadoProductoAdapter epa = new EstadoProductoAdapter();
    		
    		UnidadMedida um = null;
    		UnidadMedidaAdapter uma = new UnidadMedidaAdapter();
    		
    		Marca m = null;
    		MarcaAdapter ma = new MarcaAdapter();
    		
    		SubRubro sr = null;
    		SubRubroAdapter sra = new SubRubroAdapter();
    		
    		List<UMProducto> umsp = null;
    		UMProductoAdapter umpa = new UMProductoAdapter();
    		
    		if(result.next()){
    			String descripcion = result.getString("descProducto");
    			String caracteristicas = result.getString("caracteristicasProd");
    			Integer IdEstadoProducto = result.getInt("IdEstadoProducto");
    			Integer IdUmStock = result.getInt("IdUmStock");
    			Integer IdMarca = result.getInt("IdMarca");
    			Integer IdSubRubro = result.getInt("IdSubRubro");
    			ep = epa.devolverEstadoProducto(IdEstadoProducto);
    			um = uma.devolverUnidadMedida(IdUmStock);
    			m = ma.devolverMarca(IdMarca);
    			sr = sra.devolverSubRubro(IdSubRubro);
    			p = new Producto(id, descripcion, ep, um, m, sr, caracteristicas, true);
    			umsp = umpa.devolverUMProducto(p);
    			p.setUmsProducto(umsp);
    		}
    	}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		//conn.close();
    		cerrarConexion(conn);
    	}
		return p;
    }
	
	public List<Producto> devolverProductos() throws Exception {
		Connection conn = null;
		List<Producto> productos = new ArrayList<Producto>();
		
		EstadoProductoAdapter epa = new EstadoProductoAdapter();
		EstadoProducto ep = null;
		UnidadMedidaAdapter uma = new UnidadMedidaAdapter();
		UnidadMedida um = null;
		MarcaAdapter ma = new MarcaAdapter();
		Marca m = null;
		SubRubroAdapter sra = new SubRubroAdapter();
		SubRubro sr = null;
		UMProductoAdapter umpa = new UMProductoAdapter();
		List<UMProducto> umsp = null;
    	PreparedStatement stmt = null;
		try {
			conn = (Connection) abrirConexion();
    		Producto p = null;
    		String sel = "SELECT * FROM producto WHERE prodHabilitado = 1";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		ResultSet result = stmt.executeQuery(sel);
    		while(result.next()){
    			String id = result.getString("IdProducto");
    			String descripcion = result.getString("descProducto");
    			Integer idEstadoProd = result.getInt("IdEstadoProducto");
    			Integer idUmStock = result.getInt("IdUmStock");
    			Integer idMarca = result.getInt("IdMarca");
    			Integer idSubRubro = result.getInt("IdSubRubro");
    			String caracteristicas = result.getString("caracteristicasProd");
    			
    			ep = epa.devolverEstadoProducto(idEstadoProd);
    			um = uma.devolverUnidadMedida(idUmStock);
    			m = ma.devolverMarca(idMarca);
    			sr = sra.devolverSubRubro(idSubRubro);
    			
    			p = new Producto(id, descripcion, ep, um, m, sr, caracteristicas, true);
    			umsp = umpa.devolverUMProducto(p);
    			p.setUmsProducto(umsp);
    			
    			productos.add(p);
    		}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		//conn.close();
    		cerrarConexion(conn);
    	}
    	return productos;
	}
	
	public List<Producto> buscarProductos(String descripcion, String id_marca, String id_rubro, String id_subrubro, String id_categoria, Proveedor proveedor) throws Exception{
		
		Connection conn = null;
    	List<Producto> productos = new ArrayList<Producto>();
    	PreparedStatement stmt = null;
		try {
			conn = (Connection) abrirConexion();
			Integer i = 0;
			Producto p = null;
			
			String agregarProveedor = "";
			
    		if(proveedor != null){
    			agregarProveedor = " INNER JOIN proveedor_producto pp on p.IdProducto = pp.IdProducto";
       		}
    		
    		String sel = "SELECT * from producto p " +
    					 "INNER JOIN subrubro sr on p.IdSubRubro = sr.IdSubRubro " +
    					 "INNER JOIN rubro r on sr.IdRubro = r.IdRubro " +
    					 "INNER JOIN categoria c on r.IdCategoria = c.IdCategoria "+ agregarProveedor +" WHERE";
    		
    		if(proveedor != null){
    			if(i == 0){
    				sel = sel + " pp.IdProveedor = ?";
    			}else{
    				sel = sel + " AND pp.IdProveedor = ?";	
    			}
    			i++;
    		}
    		
    		if(id_categoria != null){
    			if(i == 0){
    				sel = sel + " c.IdCategoria = ?";
    			}else{
    				sel = sel + " AND c.IdCategoria = ?";	
    			}
    			i++;
    		}
    		if(id_marca != null){
    			if(i == 0){
    				sel = sel + " p.IdMarca = ?";
    			}else{
    				sel = sel + " AND p.IdMarca = ?";	
    			}
    			i++;
    		}
    		if(id_rubro != null){
    			if(i == 0){
    				sel = sel + " r.IdRubro = ?";
    			}else{
    				sel = sel + " AND r.IdRubro = ?";	
    			}
    			i++;
    		}
    		if(id_subrubro != null){
    			if(i == 0){
    				sel = sel + " sr.IdSubRubro = ?";
    			}else{
    				sel = sel + " AND sr.IdSubRubro = ?";	
    			}
    			i++;
    		}
    		if(descripcion != null){
    			if(i == 0){
    				sel = sel + " p.descProducto LIKE ?";
    			}else{
    				sel = sel + " AND p.descProducto LIKE ?";	
    			}
    			i++;
    		}
    		    		
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		
    		if(descripcion != null){
    			stmt.setString(i, "%" + descripcion + "%");
    			i--;
    		}
    		if(id_subrubro != null){
    			stmt.setInt(i, Integer.parseInt(id_subrubro));
    			i--;
    		}
    		if(id_rubro != null){
    			stmt.setInt(i, Integer.parseInt(id_rubro));
    			i--;
    		}
    		if(id_marca != null){
    			stmt.setInt(i, Integer.parseInt(id_marca));
    			i--;
    		}
    		if(id_categoria != null){
    			stmt.setInt(i, Integer.parseInt(id_categoria));
    			i--;
    		}
    		
    		if(proveedor != null){
    			stmt.setInt(i, proveedor.getIdProvedoor());
    			i--;
    		}
    		
    		ResultSet result = stmt.executeQuery();
    		EstadoProducto ep = null;
    		EstadoProductoAdapter epa = new EstadoProductoAdapter();
    		
    		UnidadMedida um = null;
    		UnidadMedidaAdapter uma = new UnidadMedidaAdapter();
    		
    		Marca m = null;
    		MarcaAdapter ma = new MarcaAdapter();
    		
    		List<UMProducto> umsp = null;
    		UMProductoAdapter umpa = new UMProductoAdapter();
    		
    		SubRubro sr = null;
    		SubRubroAdapter sra = new SubRubroAdapter();
    		while(result.next()){
    			String id = result.getString("IdProducto");
    			String descProd = result.getString("descProducto");
    			String caracteristicas = result.getString("caracteristicasProd");
    			Integer IdEstadoProducto = result.getInt("IdEstadoProducto");
    			Integer IdUmStock = result.getInt("IdUmStock");
    			Integer IdMarca = result.getInt("IdMarca");
    			Integer IdSubRubro = result.getInt("IdSubRubro");
    			ep = epa.devolverEstadoProducto(IdEstadoProducto);
    			um = uma.devolverUnidadMedida(IdUmStock);
    			m = ma.devolverMarca(IdMarca);
    			sr = sra.devolverSubRubro(IdSubRubro);
    			p = new Producto(id, descProd, ep, um, m, sr, caracteristicas, true);
    			umsp = umpa.devolverUMProducto(p);
    			p.setUmsProducto(umsp);
    			productos.add(p);
    		}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		//conn.close();
    		cerrarConexion(conn);
    	}
		return productos;
	}
	
	public void agregarProducto(Producto p) throws Exception {
		Connection conn = null;
		PreparedStatement stmt = null;
		UMProductoAdapter uma = new UMProductoAdapter();
		UMProducto ump = null;
		PrecioProductoAdapter ppa = new PrecioProductoAdapter();
		try {
	    	conn = (Connection) abrirConexion();
	    	conn.setAutoCommit(false);
	    	String add = "INSERT INTO producto(IdProducto,descProducto,IdEstadoProducto,IdUmStock,IdMarca,IdSubRubro,caracteristicasProd,prodHabilitado) " +
					"VALUES (?,?,?,?,?,?,?,1)";
			stmt = (PreparedStatement) conn.prepareStatement(add);
			stmt.setString(1, p.getIdProducto());
			stmt.setString(2, p.getDescProducto());
			stmt.setInt(3, p.getEstadoProducto().getIdEstadoProducto());
			stmt.setInt(4, p.getUnidadMedidaStock().getIdUnidadMedida());
			stmt.setInt(5, p.getMarca().getIDMarca());
			stmt.setInt(6, p.getSubRubro().getIdSubRubro());
			stmt.setString(7, p.getCaracteristicasProd());
	    	stmt.execute();
	    	
	    	List<UMProducto> umsp = p.getUmsProducto();
	    	// creo UM Stock como UM Producto
	    	ump = new UMProducto(p, p.getUnidadMedidaStock(), null, null, p.getUnidadMedidaStock().getDescUnidadMedida(), false, true);
	    	umsp.add(ump);
	    	// creo Lista de UM Producto
	    	boolean okay = uma.agregarUMProducto(umsp, p.getIdProducto(), conn);
	    	if(okay){
	    		// creo Lista de Precios Producto
	    		boolean okay2 = ppa.agregarPreciosProdcuto(p.getPrecios(), conn);
	    		if(okay2){
	    			conn.commit();
	    		}else{
	    			conn.rollback();
	    			throw new Exception("Error al guardar Precios Producto al insertar Producto");
	    		}
	    	}else{
	    		conn.rollback();
	    		throw new Exception("Error al guardar Unidad de Medida al insertar Producto");
	    	}
    	}
    	catch (Exception e) {
    		conn.rollback();
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}
	
	public void eliminarProducto(Producto p) throws Exception {
		Connection conn = null;
    	PreparedStatement stmt = null;
    	try {
	    	conn = (Connection) abrirConexion();
	    	String del = "UPDATE producto SET prodHabilitado = 0 WHERE IdProducto = ?";
	    	stmt = (PreparedStatement) conn.prepareStatement(del);
	    	stmt.setString(1, p.getIdProducto());
			stmt.execute();
		}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}
	
	public void modificarProducto(Producto p, List<UMProducto> umProdNuevas) throws Exception {
		Connection conn = null;
		UMProductoAdapter umpa = new UMProductoAdapter();
    	PreparedStatement stmt = null;
    	PrecioProductoAdapter ppa = new PrecioProductoAdapter();
    	try {
	    	conn = (Connection) abrirConexion();
	    	conn.setAutoCommit(false);
	    	String upd = "UPDATE producto SET descProducto = ?,IdEstadoProducto = ?,IdUmStock = ?,IdMarca = ?,IdSubRubro = ?,caracteristicasProd = ? WHERE IdProducto = ? ";
	    	stmt = (PreparedStatement) conn.prepareStatement(upd);
	    	stmt.setString(1, p.getDescProducto());
	    	stmt.setInt(2, p.getEstadoProducto().getIdEstadoProducto());
	    	stmt.setInt(3, p.getUnidadMedidaStock().getIdUnidadMedida());
	    	stmt.setInt(4, p.getMarca().getIDMarca());
	    	stmt.setInt(5, p.getSubRubro().getIdSubRubro());
	    	stmt.setString(6, p.getCaracteristicasProd());
	    	stmt.setString(7, p.getIdProducto());
			stmt.execute();
			
			// inserto las nuevas UM Producto
			boolean insertUMProd = umpa.agregarUMProducto(umProdNuevas, p.getIdProducto(), conn);
			if (insertUMProd){
				// modifico las UM Producto viejas (actualizo y elimino)
				boolean modificarUM = (p.getUmsProducto()!=null)?umpa.modificarUMProducto(p.getUmsProducto(), conn):true;
		    	if(modificarUM){
		    		// inserto los nuevos precios Producto
		    		boolean guardarPrecios = (p.getPrecios()!=null)?ppa.agregarPreciosProdcuto(p.getPrecios(), conn):true;
		    		if (guardarPrecios){
		    			conn.commit();
		    		}else{
		    			conn.rollback();
			    		throw new Exception("Error al Guardar Precios Producto");
		    		}
		    	}else{
		    		conn.rollback();
		    		throw new Exception("Error al Modificar Unidad de Medida Producto");
		    	}
			}else{
				conn.rollback();
	    		throw new Exception("Error al Insertar nuevas Unidad de Medida Producto");
			}
		}
    	catch (Exception e) {
    		conn.rollback();
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}
	
	public List<Producto> devolverProductosProveedor(Proveedor prov) throws Exception {
		Connection conn = null;
		List<Producto> productos = new ArrayList<Producto>();
		
		EstadoProductoAdapter epa = new EstadoProductoAdapter();
		EstadoProducto ep = null;
		UnidadMedidaAdapter uma = new UnidadMedidaAdapter();
		UnidadMedida um = null;
		MarcaAdapter ma = new MarcaAdapter();
		Marca m = null;
		SubRubroAdapter sra = new SubRubroAdapter();
		SubRubro sr = null;
		UMProductoAdapter umpa = new UMProductoAdapter();
		List<UMProducto> umsp = null;
    	PreparedStatement stmt = null;
		try {
			conn = (Connection) abrirConexion();
    		Producto p = null;
    		String sel = "SELECT * FROM proveedor_producto pp INNER JOIN producto p on pp.IdProducto=p.IdProducto  WHERE IdProveedor = ?";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setInt(1, prov.getIdProvedoor());
    		ResultSet result = stmt.executeQuery();
    		
    		while(result.next()){
    			String id = result.getString("IdProducto");
    			String descripcion = result.getString("descProducto");
    			Integer idEstadoProd = result.getInt("IdEstadoProducto");
    			Integer idUmStock = result.getInt("IdUmStock");
    			Integer idMarca = result.getInt("IdMarca");
    			Integer idSubRubro = result.getInt("IdSubRubro");
    			String caracteristicas = result.getString("caracteristicasProd");
    			
    			ep = epa.devolverEstadoProducto(idEstadoProd);
    			um = uma.devolverUnidadMedida(idUmStock);
    			m = ma.devolverMarca(idMarca);
    			sr = sra.devolverSubRubro(idSubRubro);
    			
    			p = new Producto(id, descripcion, ep, um, m, sr, caracteristicas, true);
    			umsp = umpa.devolverUMProducto(p);
    			p.setUmsProducto(umsp);
    			
    			productos.add(p);
    		}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		//conn.close();
    		cerrarConexion(conn);
    	}
    	return productos;
	}

}
